package com.company.pattern;

/**
 *  懒汉单例模式
 */
public class SingletonLazy {


//    /**
//     * 方式一，线程不安全，多线程场景下存在安全问题
//     * @return
//     */
//    private static SingletonLazy instance;
//
//    /**
//     * 构造函数私有化，保证外部不能通过new方式创建对象
//     */
//    private SingletonLazy(){}
//
//    /**
//     * 对外暴露一个方法获取单例类对象
//     * @return
//     */
//    public static SingletonLazy getInstance(){
//        if(instance == null){
//            instance = new SingletonLazy();
//        }
//        return instance;
//    }
//
//    /**
//     * 单例对象中某个方法，如果可以调用即代表成功创建单例对象
//     */
//    public void test(){
//        System.out.println("This is a lazy singleton pattern method");
//    }



//    /**
//     * 方式二，对方法加锁解决线程安全问题，但锁粒度太大影响性能
//     * @return
//     */
//    private static SingletonLazy instance;
//    private SingletonLazy(){}
//    public static synchronized SingletonLazy getInstance(){
//        if(instance == null){
//            instance = new SingletonLazy();
//        }
//        return instance;
//    }


//    /**
//     * 方式三，double checked locking双重检查锁定，确保多线程场景下保持高性能
//     * @return
//     */
//    private static SingletonLazy instance;
//    private SingletonLazy(){}
//    public static  SingletonLazy getInstance(){
//        //第一重检查
//        if(instance == null){
//            // 假如A和B两个线程同时执行到synchronized(SingletonLazy.class)这一行，则需要第二重检查来防止重复new对象
//            synchronized (SingletonLazy.class){
//                //第二重检查
//                if(instance == null) {
//                    instance = new SingletonLazy();
//                }
//            }
//        }
//        return instance;
//    }


    /**
     * 方式四，使用关键字volatile修饰保证有序性和可见性，禁止CPU指令重排
     */
    private static volatile SingletonLazy instance;
    private SingletonLazy(){}
    public static SingletonLazy getInstance(){
        //第一重检查
        if(instance == null){
            // 假如A和B两个线程同时执行到synchronized(SingletonLazy.class)这一行，则需要第二重检查来防止重复new对象
            synchronized (SingletonLazy.class){
                //第二重检查
                if(instance == null) {
                    instance = new SingletonLazy();
                }
            }
        }
        return instance;
    }

    /**
     * 单例对象中某个方法，如果可以调用即代表成功创建单例对象
    */
    public void test(){
        System.out.println("This is a lazy singleton pattern method");
    }

    public static void main(String[] args) {
        SingletonLazy.getInstance().test();
    }

}
